package com.dingreading.cloud.admin.controller;

import com.alibaba.excel.util.StringUtils;
import com.dingreading.cloud.admin.dto.CmorderDto;
import com.dingreading.cloud.admin.dto.CmservicesDto;
import com.dingreading.cloud.admin.entity.*;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.OrderAmountSplitUtil;
import com.dingreading.cloud.admin.util.bean.CmorderUtil;
import com.dingreading.cloud.admin.util.bean.FollowUtil;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.qyweixin.AccessTokenDto;
import com.dingreading.cloud.common.util.qyweixin.QyWeiXinUtil;
import com.dingreading.cloud.common.util.qyweixin.QyWeixinMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/system/cmOrder")
@Api(tags = "总部-会员服务订单管理")
public class CmOrderController {

    @Value("${serverUrl}")
    private String serverUrl;
    @Value("${qyweixin.corpid}")
    private String corpid;
    @Value("${qyweixin.secret}")
    private String secret;
    @Value("${qyweixin.agentid}")
    private String agentid;
    @Value("${qyweixin.firststorechatid}")
    private String firststorechatid;
    @Value("${qyweixin.secondstorechatid}")
    private String secondstorechatid;
    @Value("${qyweixin.thirdstorechatid}")
    private String thirdstorechatid;
    @Value("${qyweixin.fourthstorechatid}")
    private String fourthstorechatid;
    @Value("${qyweixin.fifthstorechatid}")
    private String fifthstorechatid;
    @Value("${qyweixin.ninthstorechatid}")
    private String ninthstorechatid;

    @Resource
    private CmordersService cmordersService;
    @Resource
    private CmservicesService cmservicesService;
    @Resource
    private CmpaypicsService cmpaypicsService;
    @Resource
    private MemberFollowService memberFollowService;
    @Resource
    private OrderStatusLogsService orderStatusLogsService;
    @Resource
    private StoresService storesService;
    @Resource
    private OrderAmountSplitUtil orderAmountSplitUtil;
    @Resource
    private RedisService redisService;


    @ApiOperation(value = "分页列表")
    @PostMapping(value = "/pageList")
    public R<Object> pageList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid", required = false) String storeUid,
            @ApiParam(value = "收入类型") @RequestParam(value = "orderType", required = false) List<String> orderType,
            @ApiParam(value = "订单号/会员姓名/合同号") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "角色类型 1.财务") @RequestParam(value = "roleType", required = false) Integer roleType,
            @ApiParam(value = "订单金额") @RequestParam(value = "orderAmount", required = false) Double orderAmount,
            @ApiParam(value = "收款开始日期") @RequestParam(value = "beginDate", required = false) String beginDate,
            @ApiParam(value = "收款结束日期") @RequestParam(value = "endDate", required = false) String endDate,
            @ApiParam(value = "审批开始日期") @RequestParam(value = "checkBeginDate", required = false) String checkBeginDate,
            @ApiParam(value = "审批结束日期") @RequestParam(value = "checkEndDate", required = false) String checkEndDate,
            @ApiParam(value = "财务审核状态 0.待审批 1.通过 -1.退回") @RequestParam(value = "status", required = false) Integer status
    ) {
        List<String> selfAndJoinCorpUidList = storesService.corpUidBySelfAndConsortium();
        if (roleType != null && roleType.equals(1))
            selfAndJoinCorpUidList = storesService.corpUidBySelfAndConsortium();

        PageDto<CmorderDto> page = cmordersService.page(
                pageUtil, selfAndJoinCorpUidList, storeUid, keyword, orderType, status, beginDate, endDate, checkBeginDate, checkEndDate,
                orderAmount
        );
        List<CmorderDto> results = page.getList();
        if (CollectionUtils.isNotEmpty(results)) {
            List<String> orderCodes = new ArrayList<>();
            for (CmorderDto dto : results) {
                String orderCode = dto.getOrderCode();
                orderCodes.add(orderCode);
            }

            // 查订单服务
            List<CmservicesDto> cmservicesList = cmservicesService.dtoListByOrderCodes(storeUid, orderCodes);
            Map<String, List<CmservicesDto>> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(cmservicesList))
                map = cmservicesList.stream().collect(Collectors.groupingBy(CmservicesDto::getOrderCode));

            // 查付款截图
            List<Cmpaypics> pays = cmpaypicsService.getByOrderCodes(orderCodes);
            Map<String, List<Cmpaypics>> payMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(pays))
                payMap = pays.stream().collect(Collectors.groupingBy(Cmpaypics::getOrderCode));

            // 查最近的审批记录
//            List<OrderStatusLogs> logsList = orderStatusLogsService.lastListByOrderCode(orderCodes);
//            Map<String, List<OrderStatusLogs>> logMap =new HashMap<>();
//            if (CollectionUtils.isNotEmpty(logsList)) {
//                 logMap = logsList.stream().collect(Collectors.groupingBy(OrderStatusLogs::getOrderCode));
//            }

            for (CmorderDto dto : results) {
                String orderCode = dto.getOrderCode();
                dto.setServiceList(map.get(orderCode));
                dto.setPays(payMap.get(orderCode));

//                List<OrderStatusLogs> logs = logMap.get(orderCode);
//                if (CollectionUtils.isNotEmpty(logs)) {
//                    OrderStatusLogs log = logs.get(0);
//                    dto.setCheckName(log.getOpStaffFullName());
//                    dto.setCheckTime(DateUtil.getDefaultTimeStr(log.getAddTime()));
//                }
            }
        }

        PageBeanDto data = new PageBeanDto();
        data.setTotal(page.getTotal());
        data.setList(results);
        return R.ok(data);
    }

    @ApiOperation(value = "获取服务订单信息")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "会员uid") @RequestParam(value = "memberUid") String memberUid,
            @ApiParam(value = "服务订单编号") @RequestParam(value = "orderCode") String orderCode
    ) {
        CmorderDto data = cmordersService.getDtoByOrderCode(storeUid, memberUid, orderCode);
        if (null == data)
            return R.fail("服务订单获取失败");

        List<Cmpaypics> pays = cmpaypicsService.getByOrderCode(orderCode);
        List<OrderStatusLogs> logs = orderStatusLogsService.listByOrderCode(orderCode);

        List<CmservicesDto> services = cmservicesService.dtoListByOrderCode(storeUid, memberUid, orderCode);
        CmorderUtil.setUseLessonCntAndStatusName(services, null);

        data.setPays(pays);
        data.setServices(services);
        data.setLogs(logs);

        return R.ok(data);
    }

    @ApiOperation(value = "财务审批会员订单")
    @PostMapping(value = "/updateStatus", produces = "application/json; charset=UTF-8")
    public R<Object> updateStatus(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工姓名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "服务订单编号") @RequestParam(value = "orderCode") String orderCode,
            @ApiParam(value = "财务审批状态 1.审批通过 -1.审批拒绝") @RequestParam(value = "status") Integer status,
            @ApiParam(value = "审批备注") @RequestParam(value = "remark", required = false) String remark
    ) {
        if (status.equals(-1) && StringUtils.isBlank(remark))
            return R.fail("请填写审批备注");

        String statusName = "";
        if (status.equals(1))
            statusName = "审批通过";
        else if (status.equals(-1))
            statusName = "审批拒绝";
        else
            return R.fail("审批状态错误");

        Cmorders data = cmordersService.getByOrderCode(null, null, orderCode);
        if (null == data) return R.fail("会员订单获取失败");

        Stores stores = storesService.getByUid(data.getStoreUid());
        if (null == stores)
            return R.fail("门店信息获取失败");

        Integer operationType = stores.getOperationType();
        if (!AccountUtil.isSelfAndConsortiumStore(operationType))
            return R.fail("不是自营或联营店的会员订单，不能操作");
        if (data.getStatus().equals(status))
            return R.fail(data.getStatusName() + "，不能操作");
        if (data.getStatus().equals(1)) {
            OrderStatusLogs log = orderStatusLogsService.getLastByOrderCode(orderCode);
            if (log != null && TimeUtil.moreThanDay(log.getAddTime(), 30))
                return R.fail("审批通过已超过30天，不能操作");
        }

        boolean l = cmordersService.updateStatus(orderCode, status, statusName);
        if (!l)
            return R.fail("审批失败");

        OrderStatusLogs logs = new OrderStatusLogs();
        logs.setCorpUid(data.getCorpUid());
        logs.setStoreUid(data.getStoreUid());
        logs.setOrderCode(orderCode);
        logs.setStatus(status);
        logs.setStatusName(statusName);
        logs.setRemark(remark);
        logs.setOpStaffUid(headStaffUid);
        logs.setOpStaffFullName(headStaffName);
        orderStatusLogsService.saveOrUpdate(logs);

        // 跟进记录
        String followType = EnumType.Follow.AUDIT_ORDER.getType();
        String followTypeName = EnumType.Follow.AUDIT_ORDER.getName();
        String content = StringUtils.isBlank(remark) ? "订单编号： " + orderCode + "，" + statusName :
                "订单编号： " + orderCode + "，" + statusName + "；备注：" + remark;
        MemberFollow follow = FollowUtil.newFollow(
                data.getCorpUid(), data.getStoreUid(), data.getStoreName(), headStaffUid, headStaffName,
                data.getMemberUid(), data.getMemberName(), followType, followTypeName, content,
                orderCode, DateUtil.getNowDatetime()
        );
        memberFollowService.saveOrUpdate(follow);

        // 审批拒绝，给门店消息群发送通知
        if (status.equals(-1)) {
            String storeUid = data.getStoreUid();
            String chatid = "";
            if (storeUid.equals(AccountUtil.WKLS_UID))
                chatid = firststorechatid;
            else if (storeUid.equals(AccountUtil.QHY_UID))
                chatid = secondstorechatid;
            else if (storeUid.equals(AccountUtil.LHY_UID))
                chatid = thirdstorechatid;
            else if (storeUid.equals(AccountUtil.SXMD_UID))
                chatid = fourthstorechatid;
            else if (storeUid.equals(AccountUtil.SJGG_UID))
                chatid = fifthstorechatid;
            else if (storeUid.equals(AccountUtil.LHTJ_UID))
                chatid = ninthstorechatid;
            if (StringUtils.isNotBlank(chatid)) {
                // 企业微信获取access_token
                String accessToken = getQiWeiAccessToken();
                String time = DateUtil.getNowDatetimeStr();
                String msg = QyWeixinMsg.checkCmorderMsg(serverUrl, remark, data.getSaleStaffFullName(), data.getStoreName(), orderCode, time);
                QyWeiXinUtil.sendToChat(accessToken, chatid, msg);
            }
        }

        return R.ok();
    }

    @ApiOperation(value = "财务批量审批通过会员订单")
    @PostMapping(value = "/batchApproval", produces = "application/json; charset=UTF-8")
    public R<Object> batchApproval(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工姓名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "服务订单编号") @RequestParam(value = "orderCodes") List<String> orderCodes,
            @ApiParam(value = "审批备注") @RequestParam(value = "remark", required = false) String remark
    ) {
        List<CmorderDto> list = cmordersService.dotListByOrderCodeIn(orderCodes);
        if (CollectionUtils.isEmpty(list))
            return R.fail("会员订单获取失败");

        List<String> storeUidList = list.stream().map(CmorderDto::getStoreUid).distinct().collect(Collectors.toList());
        List<Stores> stores = storesService.getByUids(storeUidList);
        if (CollectionUtils.isEmpty(stores))
            return R.fail("门店信息获取失败");
        Map<String, Integer> storeOperationMap = stores.stream().collect(Collectors.toMap(Stores::getUid, Stores::getOperationType));

        for (CmorderDto data : list) {
            if (!AccountUtil.isSelfStore(storeOperationMap.get(data.getStoreUid())))
                return R.fail(data.getOrderCode() + "不是自营门店的会员订单，不能操作");
            if (data.getStatus().equals(1))
                return R.fail(data.getOrderCode() + data.getStatusName() + "，不能操作");
        }

        String statusName = "审批通过";
        boolean l = cmordersService.updateStatusByOrderCods(orderCodes, 1, statusName);
        if (!l)
            return R.fail("审批失败");

        String followType = EnumType.Follow.AUDIT_ORDER.getType();
        String followTypeName = EnumType.Follow.AUDIT_ORDER.getName();
        List<OrderStatusLogs> logsList = new ArrayList<>();
        List<MemberFollow> followList = new ArrayList<>();
        Date time = DateUtil.getNowDatetime();
        for (CmorderDto data : list) {
            OrderStatusLogs logs = new OrderStatusLogs();
            logs.setCorpUid(data.getCorpUid());
            logs.setStoreUid(data.getStoreUid());
            logs.setOrderCode(data.getOrderCode());
            logs.setStatus(1);
            logs.setStatusName(statusName);
            logs.setRemark(remark);
            logs.setOpStaffUid(headStaffUid);
            logs.setOpStaffFullName(headStaffName);
            logsList.add(logs);
            // 跟进记录
            String content = StringUtils.isBlank(remark) ? "订单编号： " + data.getOrderCode() + "，" + statusName :
                    "订单编号： " + data.getOrderCode() + "，" + statusName + "；备注：" + remark;
            MemberFollow follow = FollowUtil.newFollow(
                    data.getCorpUid(), data.getStoreUid(), data.getStoreName(), headStaffUid, headStaffName,
                    data.getMemberUid(), data.getMemberName(), followType, followTypeName, content,
                    data.getOrderCode(), time
            );
            followList.add(follow);
        }
        orderStatusLogsService.saveBatch(logsList);
        memberFollowService.saveBatch(followList);

        return R.ok();
    }


    @ApiOperation(value = "按收款日期拆分订单服务金额")
    @PostMapping(value = "/orderAmountSplitByCmservice", produces = "application/json; charset=UTF-8")
    public R<Object> orderAmountSplitByCmservice(
            @ApiParam(value = "收款开始日期") @RequestParam(value = "beginDate", required = false) String beginDate,
            @ApiParam(value = "收款结束日期") @RequestParam(value = "endDate", required = false) String endDate,
            @ApiParam(value = "门店类型 1.自营或联营 2.加盟店") @RequestParam(value = "type") int type
    ) throws Exception {
        List<Stores> storesList = new ArrayList<>();
        if (type == 1) {
            storesList = storesService.selfAndConsortiumList();
        } else if (type == 2) {
            storesList = storesService.joinList();
        }
        if (CollectionUtils.isEmpty(storesList)) {
            return R.fail("未查询到门店");
        }
        List<String> storeUidList = storesList.stream().map(Stores::getUid).collect(Collectors.toList());

        List<Cmservices> cmservicesList = cmservicesService.amountSplitList(storeUidList, beginDate, endDate);
        if (CollectionUtils.isEmpty(cmservicesList)) {
            return R.fail("未查询到服务！");
        }
        List<String> codeList = cmservicesList.stream().map(Cmservices::getOrderCode).distinct().collect(Collectors.toList());
        List<Cmorders> orderList = cmordersService.listByOrderCodeIn(codeList);
        if (CollectionUtils.isEmpty(orderList)) {
            return R.fail("订单获取失败！");
        }
        System.out.println("订单数量 = " + cmservicesList.size());
        orderAmountSplitUtil.splitServiceAmountList(orderList);

        return R.ok();
    }

    /**
     * 企业微信获取access_token
     */
    private String getQiWeiAccessToken() {
        String accessToken = (String) redisService.get(RedisParam.QYWEINXIN_ACCESS_TOKEN);
        if (StringUtils.isBlank(accessToken)) {
            AccessTokenDto dto = QyWeiXinUtil.getAccessToken(corpid, secret);
            if (dto != null) {
                accessToken = dto.getAccess_token();
                int expires_in = dto.getExpires_in();
                // redis缓存accessToken
                redisService.set(RedisParam.QYWEINXIN_ACCESS_TOKEN, accessToken, expires_in);
            }
        }
        return accessToken;
    }
}
